Skip to content

i18n: localize sidebar panel labels, status messages, and focus indicators#2921

Closed
gordonlu wants to merge 1 commit into
Hmbown:mainfrom
gordonlu:feat/i18n-sidebar
Closed

i18n: localize sidebar panel labels, status messages, and focus indicators#2921
gordonlu wants to merge 1 commit into
Hmbown:mainfrom
gordonlu:feat/i18n-sidebar

Conversation

@gordonlu

@gordonlu gordonlu commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Localizes 17 Sidebar* MessageIds across the sidebar panels, status bar focus indicators, and toggle messages.

MessageIds added

Surface MessageIds
Section titles SidebarWork, SidebarTasks, SidebarSession
Panel labels SidebarLiveTools, SidebarRecentTools, SidebarBackgroundCommands, SidebarStrategyMetadata
Empty states SidebarNoActiveWork, SidebarNoLiveTools, SidebarNoAgents
Status indicator SidebarWorkStateUpdating
Focus/hidden status SidebarFocusWork, SidebarFocusTasks, SidebarFocusAgents, SidebarFocusContext, SidebarFocusAuto, SidebarHidden

Files changed

  • localization.rs: Enum entries + ALL_MESSAGE_IDS + translations for 7 locales
  • sidebar.rs: All panel labels, empty states, work state updating replaced with tr() calls; Locale parameter threaded through helper functions
  • ui.rs: Focus status messages via keyboard shortcuts and toggle functions
  • hotbar/actions.rs: Sidebar toggle status messages
  • .gitignore: Exclude .claude/settings.json

Not localized (kept English)

  • Agents section title — product term decision
  • turn prefix — treated as object ID (like commit abc123)
  • Agent status values (running, done, etc.) — technical enum values
  • Config keys (model, provider) — technical identifiers

Testing

  • create_test_app() pins Locale::En for deterministic tests
  • All 4338 unit tests pass (only pre-existing macOS flake legacy_sse_closed_stream_reconnects_and_retries_tool_call fails)
  • cargo fmt --check clean

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request localizes various TUI sidebar strings and status messages across multiple languages. The review feedback highlights several remaining hardcoded English strings (such as 'Agents', 'turn', 'completed', and 'running') that should be localized. Additionally, the reviewer suggests pinning the locale to English in the test setup to ensure deterministic tests and simplify the assertions, rather than asserting on multiple translated variations.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

let full_texts = subagent_panel_hover_texts(&summary, &rows, usable_rows.max(1));
let full_texts = subagent_panel_hover_texts(&summary, &rows, usable_rows.max(1), app.ui_locale);

render_sidebar_section(f, area, "Agents", lines, full_texts, app);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The panel title "Agents" is still hardcoded in English here. To ensure complete localization of the sidebar, this should be translated.

Consider adding MessageId::SidebarAgents to crates/tui/src/localization.rs and using it here.

Suggested change
render_sidebar_section(f, area, "Agents", lines, full_texts, app);
render_sidebar_section(f, area, tr(app.ui_locale, MessageId::SidebarAgents), lines, full_texts, app);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, but this is intentional — Agents is a product term (like SubAgentType kind column values). Per earlier review guidance, product terms that appear consistently across the UI (Agent, SubAgent, AgentTask) are kept in English. Users of this developer tool recognize "Agents" more readily than localized alternatives in this context.

Comment on lines 827 to 833
let label = if running == 0 {
format!("Background commands: {done} completed")
format!("{bg_label}: {done} completed")
} else if done == 0 {
format!("Background commands: {running} running")
format!("{bg_label}: {running} running")
} else {
format!("Background commands: {running} running, {done} completed")
format!("{bg_label}: {running} running, {done} completed")
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The status words "completed" and "running" are hardcoded in English, and the sentence structure {bg_label}: {running} running, {done} completed is also hardcoded.

This violates the localization goal of this PR and will result in grammatically incorrect or partially untranslated strings in other languages (e.g., Japanese or Chinese).

To properly localize this, the entire status messages should be defined as parameterized MessageIds (or the status words themselves should be translated) in crates/tui/src/localization.rs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These status words (running, completed) are technical status enum values consistent with the AgentStatus display pattern used elsewhere (see SubAgents PR #2899 where status values are kept English). They are the same class as done, failed, canceled — not free-form UI copy. Creating parameterized MessageIds for every {status} × {count} combination would be excessive for what is effectively debug-level status information.

lines.push(Line::from(Span::styled(
truncate_line_to_width(
&format!("turn {turn_prefix} ({status})",),
&format!("turn {turn_prefix} ({status})"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The word "turn" is hardcoded in English here. To ensure complete localization of the sidebar, this should be defined as a localized message in crates/tui/src/localization.rs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional — turn is treated as an object ID prefix (like commit abc123 or PR #456), not UI copy. The value itself (e.g. "turn_abc123") is a technical identifier. Translating it would read as unnatural as translating "commit" in a git hash display.

Comment thread crates/tui/src/tui/sidebar.rs Outdated
Comment on lines +2803 to +2804
text.iter()
.any(|line| line == "实时工具" || line == "Live tools"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of adding language-specific checks (like "实时工具") to the test assertions to prevent failures on machines with different system locales, the tests should be made deterministic by pinning the locale in the test setup.

Please update create_test_app() (around line 2437) to explicitly set app.ui_locale = Locale::En; before returning. This ensures the tests are environment-independent and allows you to simplify the assertions back to English-only.

Suggested change
text.iter()
.any(|line| line == "实时工具" || line == "Live tools"),
text.iter()
.any(|line| line == "Live tools"),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in amended commit — create_test_app() now pins app.ui_locale = Locale::En; and assertions simplified back to English-only.

Comment thread crates/tui/src/tui/sidebar.rs Outdated
Comment on lines +2835 to +2836
text.iter()
.any(|line| line == "最近工具" || line == "Recent tools"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Following the suggestion to pin app.ui_locale = Locale::En; in create_test_app(), this assertion can be simplified to only check for "Recent tools".

Suggested change
text.iter()
.any(|line| line == "最近工具" || line == "Recent tools"),
text.iter()
.any(|line| line == "Recent tools"),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above — locale pinned in create_test_app(), assertions back to English-only.

Comment thread crates/tui/src/tui/sidebar.rs Outdated
Comment on lines +2990 to +2992
!text
.iter()
.any(|line| line.contains("后台命令") || line.contains("Background commands")),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Following the suggestion to pin app.ui_locale = Locale::En; in create_test_app(), this assertion can be simplified to only check for "Background commands".

Suggested change
!text
.iter()
.any(|line| line.contains("后台命令") || line.contains("Background commands")),
!text
.iter()
.any(|line| line.contains("Background commands")),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above — locale pinned in create_test_app(), assertions back to English-only.

@gordonlu gordonlu force-pushed the feat/i18n-sidebar branch from 30daa57 to 2d9b7c2 Compare June 9, 2026 02:45

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

… indicators

Adds 17 Sidebar* MessageIds across 7 locales (En, Vi, ZhHant, Ja, ZhHans,
PtBr, Es419) covering:

- Section titles: Work, Tasks, Session
- Panel labels: Live tools, Recent tools, Background commands,
  Strategy metadata
- Empty states: No active work, No live tools or background jobs, No agents
- Status indicator: Work state updating...
- Focus/hidden status: Sidebar focus: work/tasks/agents/context/auto,
  Sidebar hidden

Agents section title and turn prefix kept as English product terms.
All locales get explicit translations (no fallback reliance).
sidebar.rs create_test_app() pins Locale::En for deterministic tests.
@gordonlu gordonlu force-pushed the feat/i18n-sidebar branch from 2d9b7c2 to 28a1041 Compare June 9, 2026 02:49

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@Hmbown

Hmbown commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Thanks @gordonlu — we merged #2891 and #2896 from your i18n batch tonight, which moved localization.rs on main, so this slice now shows as conflicting. Could you rebase it onto current main when you get a chance?

Since the slices all touch localization.rs, the smoothest path is to rebase and push them one at a time, oldest-first (#2892#2901#2918#2919#2921#2926#2929#2932#2940) — we'll merge each promptly so the next rebase stays small. Sorry for the churn; the batch is exactly the right shape and we want all of it.

@Hmbown

Hmbown commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Closing this smaller i18n PR as superseded by the consolidation lane in #2239. #2239 covers the same surface area at broader Phase 1-4b scope and is the preferred v0.8.59 review target, though it still has its own outstanding review/fix work before merge.

@Hmbown Hmbown closed this Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

localization Localization, i18n, and non-English language support ux User experience, interaction, or presentation polish v0.8.59 Targeting v0.8.59

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants